package net.oschina.snmputil.asynchronous;

import java.io.IOException;
import java.util.Vector;

import net.oschina.snmputil.iputils.IpAlgorithmUtils;

import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.event.ResponseListener;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
/**
 * 
 异步snmp 可能用于设备发现
 * @author zdc
 *
 */
public class SnmpUtil {
	private Snmp snmp = null;
	private Address targetAddress = null;

	public void initComm() throws IOException {
		// 设置Agent方的IP和端口

		TransportMapping transport = new DefaultUdpTransportMapping();
		snmp = new Snmp(transport);
		transport.listen();
	}

	public ResponseEvent sendPDU(PDU pdu) throws IOException {
		// 设置 目标
		ResponseListener listener = new ResponseListener() {
			public void onResponse(ResponseEvent event) {
				System.out.println("---------->开始异步解析<------------");
				readResponse(event);
			}
		};
		String ip = "192.168.10.121";
		int i = IpAlgorithmUtils.getIntIp(ip);
		for (int j = 0; j < 120; j++) {
			// int
			String string = IpAlgorithmUtils.getStringIp(i + j);
			System.out.println(string);
			targetAddress = GenericAddress.parse("udp:" + string + "/"
					+ SnmpConstants.DEFAULT_COMMAND_RESPONDER_PORT);
			CommunityTarget target = new CommunityTarget();
			target.setCommunity(new OctetString("public"));
			target.setAddress(targetAddress);
			// 通信不成功时的重试次数 N+1次
			target.setRetries(0);
			// 超时时间
			target.setTimeout(2 * 1000);
			// SNMP 版本
			target.setVersion(SnmpConstants.version2c);

			// 设置监听对象

			// 发送报文
			snmp.send(pdu, target, null, listener);
		}

		return null;
	}

	public void getPDU() throws IOException {
		// PDU 对象
		PDU pdu = new PDU();
		pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.3.0")));
		// 操作类型
		pdu.setType(PDU.GETNEXT);
		ResponseEvent revent = sendPDU(pdu);
		if (null != revent) {
			readResponse(revent);
		}
	}

	@SuppressWarnings("unchecked")
	public void readResponse(ResponseEvent respEvnt) {
		// 解析Response

		System.out.println("------------>解析Response<-------------"
				+ respEvnt.getPeerAddress());
		if (respEvnt != null && respEvnt.getResponse() != null) {
			Vector<VariableBinding> recVBs = respEvnt.getResponse()
					.getVariableBindings();
			for (int i = 0; i < recVBs.size(); i++) {
				VariableBinding recVB = recVBs.elementAt(i);

				System.out.println(recVB.getOid() + " : "
						+ recVB.getVariable().toString());
			}
		}
	}

	public static void main(String[] args) throws InterruptedException {
		try {
			SnmpUtil util = new SnmpUtil();
			util.initComm();
			util.getPDU();
			Thread.sleep(200000);
		} catch (IOException e) {
			e.printStackTrace();

		}
	}
}
